package cn.coco.jf.fw.api.config;

import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.core.Controller;
import com.jfinal.json.IJsonFactory;
import com.jfinal.json.Json;
import com.jfinal.kit.PathKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.ehcache.EhCachePlugin;
import com.jfinal.plugin.redis.RedisPlugin;
import com.jfinal.render.RenderManager;
import com.jfinal.template.Engine;
import com.jfinal.template.source.ClassPathSource;
import com.jfinal.template.source.FileSource;

import cn.coco.jf.fw.api.cache.SysCacheManager;
import cn.coco.jf.fw.api.config.consts.SysConfigConst;
import cn.coco.jf.fw.api.controller.cache.SysCacheController;
import cn.coco.jf.fw.core.config.Mapping;
import cn.coco.jf.fw.core.consts.JkConst;
import cn.coco.jf.fw.core.db.SysAccessTokenTbl;
import cn.coco.jf.fw.core.db.SysGenCodeTbl;
import cn.coco.jf.fw.core.db.SysItemTbl;
import cn.coco.jf.fw.core.db.SysLogTbl;
import cn.coco.jf.fw.core.db.SysOsEnvTbl;
import cn.coco.jf.fw.core.db.SysPropTbl;
import cn.coco.jf.fw.core.db.SysPtnVerbTbl;
import cn.coco.jf.fw.core.db.SysUserTbl;
import cn.coco.jf.fw.core.db.SysVerfCodeTbl;
import cn.exlu.coco.core.utils.StringUtil;

public abstract class JkapiConfig extends JFinalConfig{

    /**
     * 常量值设置
     */
    @Override
    public void configConstant(Constants me) {
        RenderManager.me().setRenderFactory(new JkapiRenderFactory());
        me.setJsonFactory(new IJsonFactory() {
            public Json getJson() { return new JkapiJson();}});
        me.setEncoding(StringUtil.ENCODE_UTF8);

        // 设置开发模式
        me.setDevMode(SysConfigConst.CONFIG_DEV_MODE);
        // 设置引擎模板

    }

    /**
     * 模板引擎设置
     */
    @Override
    public void configEngine(Engine me) {
        
        
    }

    @Override
    public void configHandler(Handlers me) {

        me.add(new GlobalViewHandler());
//      
//      
        
    }

    /**
     * 全局拦截器
     */
    @Override
    public void configInterceptor(Interceptors me) {

    }
    
    String baseSqlTemplateStream = "/cn/coco/jf";
    String baseSqlTemplatePath = PathKit.getRootClassPath()+baseSqlTemplateStream;

    @Override
    public void configPlugin(Plugins me) {
        // 数据源配置
        DruidPlugin druidMysql = new DruidPlugin(SysConfigConst.DB_URL, SysConfigConst.DB_USERNAME, SysConfigConst.DB_PASSWD);
        druidMysql.setDriverClass(SysConfigConst.DB_DRIVER);
        druidMysql.set(SysConfigConst.DB_INITIALSIZE, SysConfigConst.DB_MINIDLE, SysConfigConst.DB_MAXACTIVE);
        me.add(druidMysql);
        arp = new ActiveRecordPlugin(JkConst.DATA_SOURCE_NAME_MYSQL, druidMysql);

        arp.setBaseSqlTemplatePath(baseSqlTemplatePath);

        // ======系统======
        arp.addSqlTemplate(new ClassPathSource(baseSqlTemplateStream, "sys/sql/sys.sql"));

        // 共通

        sqlTemplate();
        
        Mapping mapping = new Mapping(arp);
        arp.addMapping("sys_os_env_tbl", "envValue,propKey", SysOsEnvTbl.class);
        arp.addMapping("sys_gen_code_tbl", "id", SysGenCodeTbl.class);
        arp.addMapping("sys_access_token_tbl", "appId", SysAccessTokenTbl.class);
        arp.addMapping("sys_log_tbl", "id", SysLogTbl.class);
        arp.addMapping("sys_item_tbl", "itemType,itemCode", SysItemTbl.class);
        arp.addMapping("sys_ptn_verb_tbl", "ptnId", SysPtnVerbTbl.class);
        arp.addMapping("sys_prop_tbl", "propName", SysPropTbl.class);
        arp.addMapping("sys_verf_code_tbl", "verfIdf,usageIdf", SysVerfCodeTbl.class);
        arp.addMapping("sys_user_tbl", "USER_CODE", SysUserTbl.class);
        
        db(mapping);

        arp.setDialect(new MysqlDialect());
        arp.setDevMode(SysConfigConst.CONFIG_DEV_MODE);
        arp.setShowSql(SysConfigConst.CONFIG_DEV_MODE);

        me.add(arp);
        
        // 缓存插件，默认读取根目录缓存
        EhCachePlugin echCachePlugin = new EhCachePlugin();
        me.add(echCachePlugin);

        // Redis
        if(SysConfigConst.REDIS_ENABLE){
            String[] redisModules = SysConfigConst.REDIS_MODULE.split(",");
            for(String redisModule: redisModules){
                RedisPlugin rp = new RedisPlugin(redisModule, SysConfigConst.REDIS_SERVER_IP, SysConfigConst.REDIS_SERVER_PORT);
                me.add(rp);
            }
        }

    }

    /**
     * 设置访问路由
     */
    @Override
    public void configRoute(Routes me) {
        routes = new ApiRoutes();
        routes.configBefore();
        
        addController("/api/sys/cache", SysCacheController.class, "/api/sys/cache");
        controller();
        
        routes.configAfter();
        
        me.add(routes);
    }

    @Override
    public void onStart() {
        super.onStart();
        SysCacheManager.start();
    }

    @Override
    public void onStop() {
        super.onStop();
        SysCacheManager.terminal();
    }
    
    private ActiveRecordPlugin arp;
    private ApiRoutes routes;
    
    public abstract void sqlTemplate();

    public abstract void db(Mapping mapping);
    
    public abstract void controller();
    
    /**
     * 添加sql模板
     * @param sqlTemplate
     */
    protected void addSqlTemplate(String sqlTemplate){
    	arp.addSqlTemplate(new FileSource(baseSqlTemplatePath, sqlTemplate));
    }

    /**
     * 添加控制器Controller
     * @param controllerKey 请求路径
     * @param controllerClass 类
     * @param viewPath 页面路径
     */
    protected void addController(String controllerKey, Class<? extends Controller> controllerClass, String viewPath){
        routes.add(controllerKey, controllerClass, viewPath);
    }


}
    